package com.pingao.mp.modular.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pingao.mp.modular.sys.entity.Menu;
import com.pingao.mp.modular.sys.entity.Permission;
import com.pingao.mp.modular.sys.mapper.MenuMapper;
import com.pingao.mp.modular.sys.mapper.PermissionMapper;
import com.pingao.mp.modular.sys.service.UserService;
import com.pingao.mp.modular.sys.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import java.util.*;

@Service
public class MenuServiceImpl extends ServiceImpl<MenuMapper, Menu> implements MenuService {
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;

    @Override
    public List<Menu> getLoginMenu(Long userId) {
        List<Menu> menus = baseMapper.getMenusForJwt(userId);
        getUrlForMenus(menus);
        return menus;
    }

    @Override
    public List<Map<String, Object>> getList(String search) {
        return getLevelData(baseMapper.list(search), "0");
    }


    private List<Map<String, Object>> getLevelData(List<Map<String, Object>> menus, String parentId) {
        List<Map<String, Object>> result = new ArrayList<>();
        for (Map<String, Object> data : menus) {
            Object pid = data.get("parent_id");

            if (pid != null && pid.toString().equals(parentId)) {
                List<Map<String, Object>> children = getLevelData(menus, String.valueOf(data.get("id")));
                data.put("children", children);
                result.add(data);
            }
        }
        return result;
    }

    @Override
    public List<Menu> getMenuTree(Long id) {
        QueryWrapper<Menu> wrapper = new QueryWrapper<>();
        if (id == null) {
            wrapper.eq(Menu.COL_PARENT_ID, 0);
        } else {
            wrapper.eq(Menu.COL_PARENT_ID, id);
        }
        List<Menu> menus = list(wrapper);

        for (Menu menu : menus) {
            int c = count(new QueryWrapper<Menu>().eq(Menu.COL_PARENT_ID, menu.getId()));
            menu.setHasChild(c > 0);
        }

        return menus;
    }

    @Override
    public void deleteMenuById(Long s) {
        TransactionStatus transactionStatus = null;
        try {
            transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
            //删除菜单
            //删除权限表中菜单的所有数据
            QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<>();
            permissionQueryWrapper.eq(Permission.COL_MENU_ID, s);
            permissionMapper.delete(permissionQueryWrapper);
            removeById(s);
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Exception e) {
            if (transactionStatus != null) {
                dataSourceTransactionManager.rollback(transactionStatus);
            }
            throw e;
        }
    }

    @Override
    public Set<String> getMenusForJwt(Long userId) {
        List<Menu> menus = baseMapper.getMenusForJwt(userId);
        getUrlForMenus(menus);
        Set<String> urls = new HashSet<>();
        for (Menu menu : menus) {
            urls.add(menu.getUrl());
        }
        return urls;
    }

    private void getUrlForMenus(List<Menu> menus) {
        for (Menu menu : menus) {
            String url = "";
            if (menu.getModuleName() != null && menu.getModuleName().length() > 0) {
                url += "/" + menu.getModuleName();
            }
            if (menu.getActionName() != null && menu.getActionName().length() > 0) {
                url += "/" + menu.getActionName();
            }
            if (menu.getFunctionName() != null && menu.getFunctionName().length() > 0) {
                url += "/" + menu.getFunctionName();
            }
            menu.setUrl(url);
        }
    }
}
